<template>
  <label class="td-checkbox">
    <input
      v-model="checked"
      type="checkbox"
      :disabled="disabled"
      @input="handleInput"
      @change="handleChange"
    />
    <Icon :name="iconName" class="check-icon" />
    <div v-if="label" class="check-text">
      {{ label }}
    </div>
    <div v-else-if="$slots.default" class="check-text">
      <slot></slot>
    </div>
  </label>
</template>

<script lang="ts" setup>
  import { computed, ref, watch, watchEffect } from 'vue';

  defineOptions({
    name: 'CsCheckbox',
  });

  const props = defineProps<{
    modelValue?: boolean;
    label?: string;
    indeterminate?: boolean;
    circle?: boolean;
    disabled?: boolean;
  }>();
  const emit = defineEmits(['input', 'change', 'update:modelValue']);
  defineExpose({ setCheck });

  const checked = ref(false);

  const iconName = computed(() => {
    let icon = 'uncheck';
    if (props.modelValue) {
      icon = 'all_checked'; // 全选
    }
    if (props.indeterminate) {
      icon = 'half_checked'; // 部分选
    }
    if (props.circle) {
      return icon + '_circle';
    }
    return icon;
  });

  watchEffect(() => {
    checked.value = !!props.modelValue;
  });

  watch(
    () => props.indeterminate,
    (val) => {
      if (!val) {
        checked.value = false;
      }
    },
  );

  function handleInput(e) {
    emit('input', e.target.checked);
  }

  function handleChange(e) {
    emit('update:modelValue', checked.value);
    emit('change', checked.value, e);
  }

  function setCheck(data) {
    checked.value = data;
  }
</script>

<style lang="less" scoped>
  .td-checkbox {
    display: inline-flex;
    align-items: center;
    cursor: pointer;

    .check-icon {
      width: 14px;
      height: 12px;
    }

    input {
      display: none;
    }

    label {
      display: inline-flex;
    }

    .check-text {
      display: inline-block;
      margin-left: 5px;
      font-size: 12px;
      font-weight: 400;
      line-height: 12px;
    }
  }
</style>
